package sendticket

import (
	"bufio"
	"context"
	"fmt"
	"log"
	"longmen/server/pkg/common/services"
	"longmen/server/pkg/db/mysql/db_main"
	"longmen/server/pkg/grpc_client"
	"longmen/server/pkg/protobuf"
	"os"
	"strconv"
	"strings"
	"time"
)

const (
	batchSize = 1000
	// ticketQty = 3 // 每人发 3 张票
)

type Script struct {
	*services.Service
}

func (s *Script) ProvideTicket() {

	// 获取所有用户 ID
	uids, err := db_main.GetAllUserIds()
	if err != nil {
		log.Fatalf("获取用户列表失败: %v", err)
	}
	log.Printf("共获取 %d 个用户，开始排除已发放用户", len(uids))

	s.BatchSendTicket(uids, 3)
}

func (s *Script) BatchSendTicket(uids []int64, ticketQty int64) []int64 {
	successUids := make([]int64, 0)

	// 加载已发放记录
	sentMap := make(map[int64]bool)
	if f, err := os.Open("ticket_success_uids.txt"); err == nil {
		defer f.Close()
		scanner := bufio.NewScanner(f)
		for scanner.Scan() {
			line := strings.TrimSpace(scanner.Text())
			if uid, err := strconv.ParseInt(line, 10, 64); err == nil {
				sentMap[uid] = true
			}
		}
	}

	// 过滤已发放用户

	filtered := make([]int64, 0)
	for _, uid := range uids {
		if !sentMap[uid] {
			filtered = append(filtered, uid)
		}
	}
	log.Printf("剩余 %d 个未发放用户，开始发放观赛券", len(filtered))

	// 以 append 模式打开文件用于记录新增发放
	file, err := os.OpenFile("ticket_success_uids.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatalf("打开记录文件失败: %v", err)
	}
	defer file.Close()
	writer := bufio.NewWriter(file)

	// 分批处理
	for i := 0; i < len(filtered); i += batchSize {
		end := i + batchSize
		if end > len(filtered) {
			end = len(filtered)
		}
		batch := filtered[i:end]

		req := &protobuf.ProvideTicketReq{
			Uids:     batch,
			Quantity: ticketQty,
			IsAll:    false,
		}

		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
		defer cancel()

		_, err := grpc_client.GrpcLiveServer.ProvideTicket(ctx, req)
		if err != nil {
			log.Printf("发放失败：第 %d 批(%d~%d), 错误：%v", i/batchSize+1, i, end-1, err)
		} else {
			log.Printf("成功发放：第 %d 批(%d~%d),len: %v", i/batchSize+1, i, end-1, len(uids))
			for _, uid := range batch {
				_, _ = writer.WriteString(fmt.Sprintf("%d\n", uid))
			}
			writer.Flush()
			successUids = append(successUids, req.Uids...)
		}

		time.Sleep(100 * time.Millisecond)
	}

	return successUids
}
